/**
 * @Description 
 * @author tangjun
 * @date 2016年8月4日
 * 
 */
package com.ff.common.web.controller;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.ff.common.constant.FFErrorCode;
import com.ff.common.dao.model.FFCondition;
import com.ff.common.service.FFException;
import com.ff.common.util.format.JsonConvert;
import com.ff.common.util.validate.ValidatorUtil;
import com.ff.common.web.json.BaseReqJson;
import com.ff.common.web.json.BaseRspJson;
import com.ff.common.web.json.FFSysUser;
import com.ff.common.web.json.PageJson;

import cn.jeeweb.core.query.data.Condition;
import cn.jeeweb.core.query.data.PageRequest;
import cn.jeeweb.core.query.data.QueryRequest;
import cn.jeeweb.core.query.data.Queryable;
import cn.jeeweb.core.query.data.Sort;

/**
 * @Description 
 * @author tangjun
 * @date 2016年8月4日
 */
public class FFBaseController 
{
  	protected Logger log = Logger.getLogger(getClass());
	public static final String PARA = "param";
 
 
	
	protected HttpServletRequest getRequest() {
		return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
	}
 
	public String getString(String name) {
		String resultStr = getRequest().getParameter(name);
		if (resultStr == null || "".equals(resultStr)
				|| "null".equals(resultStr) || "undefined".equals(resultStr)) {
			return null;
		} else {
			return resultStr;
		}
	}
	
	@ModelAttribute
	public void init()
	{
		//String reqJson = getString(PARA);
		//log.info("the json is " + reqJson);
	}
	
	
	 @ExceptionHandler()   
	 public String exception(Exception e,HttpServletResponse response) {   
		 BaseRspJson rsp = new BaseRspJson<>();
		 
		 log.error("system error",e);
		 rsp.setErrorCode(FFErrorCode.FAIL);

		 if(e instanceof FFException)
		 {
			 rsp.setMessage(e.getMessage());
 		 }
		 else if(e instanceof org.apache.shiro.authz.UnauthorizedException)
		 {
			 rsp.setMessage("用户没有权限");

		 }
		 else 
		 {
			 rsp.setMessage("操作失败");

		 }
		 String msg = JsonConvert.ObjectToJson(rsp);
		 
		 try {
			response.setContentType("application/json;charset=utf-8");
			response.getWriter().write(msg);
			response.getWriter().flush();
			response.getWriter().close();
 		} catch (IOException e1) {
			log.error("system error",e);
		}
		 
	     return  null;
	 }  
	
	@RequestMapping("/load")
	@ResponseBody
	public BaseRspJson Load(@RequestBody BaseReqJson<?> request)
	{
	    BaseRspJson rsp = new BaseRspJson();
  		return rsp;
 	}
	
 	@RequestMapping("/index")
	public String Index(ModelMap map){
		
 		RequestMapping mappingClass = this.getClass().getAnnotation(RequestMapping.class);
 		String action = getUrlFromAnno(mappingClass);
 		action = action.replace("${admin.url.prefix}", "modules");
 		if(action.startsWith("/"))
 		{
 			action = action.substring(1, action.length());
 		}
 		map.put("action", action);
		return ReturnPage();
	}
 	
 	
 	private String getUrlFromAnno(RequestMapping mapping)
 	{
 		String url = "";
 		if(null != mapping)
 		{
 			String[] classMap = mapping.value();
 	 		if(null != classMap && classMap.length > 0)
 	 		{
 	 			url = classMap[0];
 	 		}
 		}
 		return url;
 	}
 	protected String  ReturnPage()
 	{
  		RequestMapping mappingClass = this.getClass().getAnnotation(RequestMapping.class);
 		String url = getUrlFromAnno(mappingClass);
 		url = url.replace("${admin.url.prefix}", "modules");
 		if(url.startsWith("/"))
 		{
 			url = url.substring(1, url.length());
 		}
 		
        try
		{
        	
     		StackTraceElement[] stack = new Throwable().getStackTrace();

     		Method method = null;
        	for(Method e :this.getClass().getMethods())
        	{
        		if(e.getName().equals(stack[1].getMethodName()))
        		{
        			method = e;
        			break;
        		}
        	}
 
			RequestMapping mapping = method.getAnnotation(RequestMapping.class);
			
			url = url + this.getUrlFromAnno(mapping);
			
		} catch (Exception e)
		{
			log.error("can not get method",e);
		}  
        return url;
 	}
 	


	public Queryable GetFilterCondition(BaseReqJson request)
	{
 		
		Queryable qy = QueryRequest.newQueryable();
		
		if (null != request.getFilter() && !request.getFilter().isEmpty()) {
	 		qy.setCondition(new Condition(request.getFilter()));
		}
		qy.addSort(new Sort(request.getOrder()));
 		qy.setPageable(new PageRequest(request.getPage().getCurrentPage(), request.getPage().getPageSize()));
 
		return qy;
	}
	
	public <T> T getObj(BaseReqJson request,Class<?>... clazz)
	{
		BaseReqJson<T> req = GetReq(request,clazz);
		if(null != req)
		{
			return req.getObj();
		}
		return null;
	}
	
 

	
 	protected String GetReqJson(BaseReqJson req)
	{
		if(null != req)
		{
			return JsonConvert.ObjectToJson(req);
		}
		String reqJson = getString(PARA);
  	 
		return reqJson;
	}
 	
 	protected BaseReqJson GetReq(BaseReqJson req,Class<?>... clazz)
 	{
 		Class<?>  temp = null;
 		if(null != clazz && clazz.length != 0)
 		{
 			temp = clazz[0];
 		}
 		
 		if(null != req && (null == req.getObj() ||  req.getObj().getClass() == temp))
 		{
 			return req;
 		}
 		
 		return JsonConvert.jsonToObject(GetReqJson(req), BaseReqJson.class,clazz);
 	}
	
	protected PageJson GetPage(BaseReqJson request)
	{
		PageJson page = new PageJson();
		
		BaseReqJson req = GetReq(request);
		if(null != req)
		{
			if(null != req.getPage())
			{
				return req.getPage();
			}
		}
		return page;
	}
	
	protected FFSysUser GetSysUser()
	{
		FFSysUser user = new FFSysUser();
		return user;
	}

}
